import { RouteRecordRaw } from "vue-router";
import { constantRoutes, asyncRoutes } from "@/router";
import { store } from "@/store";
import MenuAPI from "@/api/menu";
import { RouteVO } from "@/api/menu/model";
import { useUserStore } from "@/store";

const modules = import.meta.glob("../../views/**/**.vue");
const Layout = () => import("@/layout/index.vue");

/**
 * Use meta.role to determine if the current user has permission
 *
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  if (route.meta && route.meta.roles) {
    // 角色【超级管理员】拥有所有权限，忽略校验
    if (roles.includes("ROOT")) {
      return true;
    }
    return roles.some((role) => {
      if (route.meta?.roles) {
        return route.meta.roles.includes(role);
      }
    });
  }
  return false;
};

/**
 * 递归过滤有权限的动态路由
 *
 * @param routes 接口返回所有的动态路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的动态路由
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  const asyncRoutes: RouteRecordRaw[] = [];

  routes.forEach((route) => {
    const tmpRoute = { ...route }; // ES6扩展运算符复制新对象
    if (!route.name) {
      tmpRoute.name = route.path;
    }
    // 判断用户(角色)是否有该路由的访问权限
    if (hasPermission(roles, tmpRoute)) {
      if (tmpRoute.children) {
        tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles);
      }
      asyncRoutes.push(tmpRoute);
    }
  });

  // 远程返回的数据处理
  // const asyncRoutes: RouteRecordRaw[] = [];
  // routes.forEach((route) => {
  //   const tmpRoute = { ...route } as RouteRecordRaw; // 深拷贝 route 对象 避免污染
  //   if (hasPermission(roles, tmpRoute)) {
  //     // 如果是顶级目录，替换为 Layout 组件
  //     if (tmpRoute.component?.toString() == "Layout") {
  //       tmpRoute.component = Layout;
  //     } else {
  //       // 如果是子目录，动态加载组件
  //       const component = modules[`../../views/${tmpRoute.component}.vue`];
  //       if (component) {
  //         tmpRoute.component = component;
  //       } else {
  //         tmpRoute.component = modules[`../../views/error-page/404.vue`];
  //       }
  //     }

  //     if (tmpRoute.children) {
  //       tmpRoute.children = filterAsyncRoutes(route.children, roles);
  //     }

  //     asyncRoutes.push(tmpRoute);
  //   }
  // });

  return asyncRoutes;
};
// setup
export const usePermissionStore = defineStore("permission", () => {
  // state
  const routes = ref<RouteRecordRaw[]>([]);

  // actions
  function setRoutes(newRoutes: RouteRecordRaw[]) {
    routes.value = constantRoutes.concat(newRoutes);
  }

  /**
   * 生成动态路由
   *
   * @param roles 用户角色集合
   * @returns
   */
  function generateRoutes(roles: string[]) {
    return new Promise<RouteRecordRaw[]>((resolve, reject) => {
      let accessedRoutes: any = [];
      if (roles.includes("admin")) {
        // 管理员角色的用户可以直接使用所有的路由信息
        accessedRoutes = asyncRoutes || [];
      } else {
        // 非管理员用户进行路由信息的过滤,非管理员利用功能信息来代替角色进行过滤
        const userStore = useUserStore();
        roles = userStore.user.perms;
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
      }
      // commit("SET_ROUTES", accessedRoutes);
      setRoutes(accessedRoutes);
      resolve(accessedRoutes);

      // 通过网络获取接口获取所有路由
      // MenuAPI.getRoutes()
      //   .then((data) => {
      //     // 过滤有权限的动态路由
      //     const accessedRoutes = filterAsyncRoutes(data, roles);
      //     setRoutes(accessedRoutes);
      //     resolve(accessedRoutes);
      //   })
      //   .catch((error) => {
      //     reject(error);
      //   });
    });
  }

  /**
   * 获取与激活的顶部菜单项相关的混合模式左侧菜单集合
   */
  const mixLeftMenus = ref<RouteRecordRaw[]>([]);
  function setMixLeftMenus(topMenuPath: string) {
    const matchedItem = routes.value.find((item) => item.path === topMenuPath);
    if (matchedItem && matchedItem.children) {
      mixLeftMenus.value = matchedItem.children;
    }
  }
  return {
    routes,
    setRoutes,
    generateRoutes,
    mixLeftMenus,
    setMixLeftMenus,
  };
});

// 非setup
export function usePermissionStoreHook() {
  return usePermissionStore(store);
}
